package com.sky.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import cn.mybatis.mp.core.mybatis.mapper.context.Pager;
import cn.mybatis.mp.core.sql.executor.chain.QueryChain;
import com.sky.constant.MessageConstant;
import com.sky.dto.GetBorroweuestsDTO;
import com.sky.dto.UpBorroweuestsStatusDTO;
import com.sky.entity.Books;
import com.sky.entity.Borrowrequests;
import com.sky.entity.Userborrowhistory;
import com.sky.entity.Users;
import com.sky.exception.BaseException;
import com.sky.mapper.BooksMapper;
import com.sky.mapper.BorrowrequestsMapper;
import com.sky.mapper.UserborrowhistoryMapper;
import com.sky.mapper.UsersMapper;
import com.sky.service.BorrowrequestsService;
import com.sky.service.EmailService;
import com.sky.vo.GetBorroweuestsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author majun
 * @package com.sky.service.impl
 * @date 2024/12/10 22:39
 */
@Service
public class BorrowrequestsServiceImpl implements BorrowrequestsService {

    @Autowired
    private BorrowrequestsMapper borrowrequestsMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private UserborrowhistoryMapper userborrowhistoryMapper;

    @Autowired
    private BooksMapper booksMapper;

    @Autowired
    private EmailService emailService;

    /**
     * 获取借阅申请信息分页查询
     *
     * @return 分页的借阅申请信息
     */
    @Transactional
    public Pager<GetBorroweuestsVO> getBorroweuests(GetBorroweuestsDTO getBorroweuestsDTO) {
        Users user = null;

        // 根据用户姓名查询用户ID
        if (getBorroweuestsDTO.getUsername() != null && !getBorroweuestsDTO.getUsername().isEmpty()) {
            user = usersMapper.get(where -> {
                where.eq(Users::getUsername, getBorroweuestsDTO.getUsername());
            });
        }

        // 查询申请数据
        Pager<Borrowrequests> borrowrequestsPager = QueryChain.of(borrowrequestsMapper)
                .ignoreEmptyInCondition(true)
                .ignoreNullValueInCondition(true)
                .trimStringInCondition(true)
                .like(user != null && user.getUserId() != null, Borrowrequests::getUserId, user != null ? user.getUserId().toString() : null)
                .like(Borrowrequests::getStatus, getBorroweuestsDTO.getStatus().toString())
                .paging(Pager.of(getBorroweuestsDTO.getPageNumber(), getBorroweuestsDTO.getPageSize()));

        // 提取所有 userId 和 bookId
        List<Integer> userIdList = borrowrequestsPager.getResults().stream()
                .map(Borrowrequests::getUserId)
                .collect(Collectors.toList());
        List<Integer> bookIdList = borrowrequestsPager.getResults().stream()
                .map(Borrowrequests::getBookId)
                .collect(Collectors.toList());

        // 如果 userIdList 或 bookIdList 为空，直接返回空的分页结果
        if (userIdList.isEmpty() || bookIdList.isEmpty()) {
            return new Pager<>();
        }

        // 批量查询用户姓名和图书名
        Map<Integer, String> usernameMap = usersMapper.selectBatchIds(userIdList)
                .stream()
                .collect(Collectors.toMap(Users::getUserId, Users::getUsername));

        Map<Integer, String> bookNameMap = booksMapper.selectBatchIds(bookIdList)
                .stream()
                .collect(Collectors.toMap(Books::getBookId, Books::getTitle));

        // 创建 GetBorroweuestsVO 列表
        List<GetBorroweuestsVO> voList = borrowrequestsPager.getResults().stream()
                .map(borrowRequest -> {
                    GetBorroweuestsVO vo = new GetBorroweuestsVO();
                    vo.setRequestId(borrowRequest.getRequestId());
                    vo.setUsername(usernameMap.getOrDefault(borrowRequest.getUserId(), "未知用户")); // 设置用户名
                    vo.setTitle(bookNameMap.getOrDefault(borrowRequest.getBookId(), "未知书籍")); // 设置书名
                    vo.setRequestDate(borrowRequest.getRequestDate());
                    vo.setStatus(borrowRequest.getStatus());
                    vo.setReviewDate(borrowRequest.getReviewDate());
                    vo.setAdminId(borrowRequest.getAdminId());
                    vo.setComments(borrowRequest.getComments());
                    return vo;
                })
                .collect(Collectors.toList());

        // 创建包含 GetBorroweuestsVO 的 Pager 对象
        Pager<GetBorroweuestsVO> voPager = new Pager<>();
        voPager.setTotal(borrowrequestsPager.getTotal());
        voPager.setNumber(borrowrequestsPager.getNumber());
        voPager.setSize(borrowrequestsPager.getSize());
        voPager.setResults(voList);

        return voPager;

    }


    /**
     * 借阅申请状态改变
     *
     * @param upBorroweuestsStatusDTO 借阅申请状态修改参数
     */
    @Transactional
    public void upBorroweuestsStatus(UpBorroweuestsStatusDTO upBorroweuestsStatusDTO) {
        Set<String> validStatuses = new HashSet<>(Arrays.asList("已通过", "已拒绝"));

        //判断是否为所需的数据值
        if (!validStatuses.contains(upBorroweuestsStatusDTO.getStatus())) {
            throw new BaseException(MessageConstant.THE_REQUIRED_DATA_TYPES_DO_NOT_MATCH);
        }

        //查询申请信息
        Borrowrequests borrowrequests = QueryChain.of(borrowrequestsMapper)
                .eq(Borrowrequests::getRequestId, upBorroweuestsStatusDTO.getRequestId())
                .get();

        //查询图书详情
        Books books = booksMapper.get(where -> {
            where.eq(Books::getBookId, borrowrequests.getBookId());
        });

        //查询图书库存,如果为0则自动拒绝
        if (books.getStockQuantity().equals(0)) {
            // 自动设置为拒绝状态
            upBorroweuestsStatusDTO.setStatus("已拒绝");
            upBorroweuestsStatusDTO.setComments("图书库存不足，系统自动拒绝");
        } else if (upBorroweuestsStatusDTO.getStatus().equals("已拒绝") && 
                   upBorroweuestsStatusDTO.getComments().isEmpty()) {
            //如果是手动拒绝则需要添加备注，说明拒绝原因
            throw new BaseException(MessageConstant.PLEASE_ADD_A_NOTE);
        }

        // 直接long 转换为 int
        Integer adminId = (int) StpUtil.getLoginIdAsLong();

        //完善upBorroweuestsStatusDTO数据，reviewDate、adminId
        upBorroweuestsStatusDTO.setReviewDate(new Date());
        Date date = new Date();
        upBorroweuestsStatusDTO.setAdminId(adminId);

        //管理员审核后将Borroweuests数据修改，再向Userborrowhistory中插入一条数据
        //1.修改Borroweuests数据
        borrowrequestsMapper.update(upBorroweuestsStatusDTO);

        //2.处理图书库存和借阅历史
        if (upBorroweuestsStatusDTO.getStatus().equals("已通过")) {
            // 如果申请通过，创建借阅历史记录
            Userborrowhistory userborrowhistory = new Userborrowhistory();
            BeanUtils.copyProperties(borrowrequests, userborrowhistory);

            LocalDate reviewLocalDate = date.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
            LocalDate dueDate = reviewLocalDate.plusDays(30);
            Date dueDateAsDate = Date.from(dueDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

            userborrowhistory.setDueDate(dueDateAsDate);
            userborrowhistory.setBorrowDate(new Date());
            userborrowhistory.setStatus("借阅中");  // 设置状态为"借阅中"

            userborrowhistoryMapper.save(userborrowhistory);
        } else if (upBorroweuestsStatusDTO.getStatus().equals("已拒绝")) {

            // 获取用户信息
            Users user = usersMapper.get(where -> {
                where.eq(Users::getUserId, borrowrequests.getUserId());
            });

            // 发送拒绝通知邮件
            if (user != null && user.getEmail() != null) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String requestDate = dateFormat.format(borrowrequests.getRequestDate());  // 获取申请日期
                String reviewDate = dateFormat.format(upBorroweuestsStatusDTO.getReviewDate());  // 获取审核日期
                String rejectReason = upBorroweuestsStatusDTO.getComments();  // 获取拒绝原因
                String nowData = dateFormat.format(new Date());  // 获取当前日期

                emailService.sendRejectLoanRequestEmail(
                    user.getEmail(),
                    user.getUsername(),
                    books.getTitle(),
                    requestDate,    // 使用正确的申请日期
                    reviewDate,     // 使用正确的审核日期
                    rejectReason,   // 使用正确的拒绝原因
                    nowData         // 添加当前日期
                );
            }
        }
    }
}
